import { test } from "node:test";
import { spawn } from "node:child_process";
import { assertEqual } from "snapshot-fixtures";
import stripAnsi from "strip-ansi";

const wait = (timeout = 500) => new Promise(res => setTimeout(res, timeout));

const options = { timeout: 10000, skip: true };

test("ast-explorer", options, async (t) => {
	await t.test("works", async () => {
		const decoder = new TextDecoder();

		function write(child, command) {
			child.stdin.write(command + "\r\n");
		}

		const child = spawn("node", ["./dist/cli.mjs", "ast-explorer"], { stdio: "pipe" });

		child.stdout.on("data", (d) => out.push(decoder.decode(d)));
		child.stderr.on("data", (d) => out.push(decoder.decode(d)));

		const out = [];

		await wait();
		write(child, "'Hello World'");
		await wait();
		write(child, "close()")
		await wait();

		// TODO indentation
		const expected = `Entering ast-explorer
> {
	Ok: {
		hashbang_comment: undefined,
		items: [
			{
				Expression: {
					StringLiteral: [ 'Hello World', 'Single', { start: 0, end: 13 } ]
				}
			}
		],
		span: { start: 0, end: 13 }
	}
}
> `;

		assertEqual(stripAnsi(out.join("")), expected);
	});
});

test("type checking repl", options, async (t) => {
	await t.test("works", async () => {
		const decoder = new TextDecoder();

		function write(child, command) {
			child.stdin.write(command + "\r\n");
		}

		const child = spawn("node", ["./dist/cli.mjs", "repl"], { stdio: "pipe" });

		child.stdout.on("data", (d) => out.push(decoder.decode(d)));
		child.stderr.on("data", (d) => out.push(decoder.decode(d)));

		const out = [];

		await wait();
		write(child, "const var1: string = 5 + 6;");
		await wait();
		write(child, "close()")
		await wait();

		const expected = `Entering REPL\n> error: \n  ┌─ CLI.tsx:1:22\n  │\n1 │ const var1: string = 5 + 6;\n  │             ------   ^^^^^ Type 11 is not assignable to type string\n  │             │         \n  │             Variable declared with type string\n\n\n> `;

		assertEqual(stripAnsi(out.join("")), expected);
	});
});
